import * as fs from 'fs';
import * as path from 'path';
import * as vscode from 'vscode';
import { promisify } from 'util';

const writeFileAsync = promisify(fs.writeFile);
const mkdirAsync = promisify(fs.mkdir);

/**
 * 配置类型
 */
export interface NginxConfig {
    server: {
        listen: number;
        server_name: string;
        enable_https?: boolean;
        gzip?: boolean;
        client_max_body_size?: string;
    };
    locations: Array<{
        path: string;
        type: 'proxy' | 'static' | 'redirect';
        proxy_pass?: string;
        root?: string;
        index?: string;
        try_files?: string;
        return?: string;
    }>;
    advanced?: {
        enable_gzip: boolean;
        client_max_body_size: string;
    };
}

/**
 * Nginx配置生成器
 */
export class ConfigGenerator {
    /**
     * 将JSON配置转换为Nginx配置字符串
     */
    public static generateConfig(config: NginxConfig): string {
        let nginxConfig = '';
        
        // 添加基础配置
        nginxConfig += `server {\n`;
        
        // 服务器配置
        nginxConfig += `    listen ${config.server.listen}${config.server.enable_https ? ' ssl' : ''};\n`;
        nginxConfig += `    server_name ${config.server.server_name};\n`;
        
        // 如果启用HTTPS
        if (config.server.enable_https) {
            nginxConfig += `    ssl_certificate /etc/nginx/ssl/server.crt;\n`;
            nginxConfig += `    ssl_certificate_key /etc/nginx/ssl/server.key;\n`;
            nginxConfig += `    ssl_protocols TLSv1.2 TLSv1.3;\n`;
        }
        
        // 高级选项 - 兼容两种配置方式
        const enableGzip = config.advanced?.enable_gzip || config.server.gzip;
        const clientMaxBodySize = config.advanced?.client_max_body_size || config.server.client_max_body_size || '1m';
        
        if (enableGzip) {
            nginxConfig += `    gzip on;\n`;
            nginxConfig += `    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;\n`;
        }
        
        nginxConfig += `    client_max_body_size ${clientMaxBodySize};\n`;
        
        // 添加locations
        for (const location of config.locations) {
            nginxConfig += `\n    location ${location.path} {\n`;
            
            // 根据类型生成不同配置
            switch (location.type) {
                case 'proxy':
                    if (location.proxy_pass) {
                        nginxConfig += `        proxy_pass ${location.proxy_pass};\n`;
                        nginxConfig += `        proxy_set_header Host $host;\n`;
                        nginxConfig += `        proxy_set_header X-Real-IP $remote_addr;\n`;
                        nginxConfig += `        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n`;
                    }
                    break;
                
                case 'static':
                    if (location.root) {
                        nginxConfig += `        root ${location.root};\n`;
                    }
                    if (location.index) {
                        nginxConfig += `        index ${location.index};\n`;
                    }
                    if (location.try_files) {
                        nginxConfig += `        try_files ${location.try_files};\n`;
                    }
                    break;
                
                case 'redirect':
                    if (location.return) {
                        nginxConfig += `        return ${location.return};\n`;
                    }
                    break;
            }
            
            nginxConfig += `    }\n`;
        }
        
        nginxConfig += `}\n`;
        
        return nginxConfig;
    }
    
    /**
     * 保存配置到文件
     */
    public static async saveConfig(config: NginxConfig, workspaceFolder: vscode.WorkspaceFolder): Promise<string> {
        try {
            // 确保目录存在
            const nginxDir = path.join(workspaceFolder.uri.fsPath, '.nginx');
            const confDir = path.join(nginxDir, 'conf');
            
            try {
                await mkdirAsync(nginxDir, { recursive: true });
                await mkdirAsync(confDir, { recursive: true });
            } catch (err) {
                // 忽略目录已存在的错误
            }
            
            // 生成配置
            const configString = this.generateConfig(config);
            
            // 保存到文件
            const configPath = path.join(confDir, 'nginx.conf');
            await writeFileAsync(configPath, configString, 'utf8');
            
            return configPath;
        } catch (error) {
            console.error('Failed to save Nginx config:', error);
            throw new Error(`Failed to save Nginx config: ${error instanceof Error ? error.message : String(error)}`);
        }
    }
} 